package org.devocean.groupbuying.service.impl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.devocean.groupbuying.dao.DealDAO;
import org.devocean.groupbuying.dao.DiscountDAO;
import org.devocean.groupbuying.domain.Deal;
import org.devocean.groupbuying.domain.Discount;
import org.devocean.groupbuying.domain.Formula;
import org.devocean.groupbuying.domain.PurchaseItem;
import org.devocean.groupbuying.service.DealService;
import org.devocean.groupbuying.service.ExploredService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class DealServiceImpl implements DealService {

	@Autowired
	private DealDAO dealDAO;
	
	@Autowired
	private DiscountDAO discountDAO;

	// @Autowired
	// private ExploredService exploredService;

	@Transactional(readOnly = true)
	public Deal getDealById(Integer id) {

		return dealDAO.findDealById(id);
	}

	@Transactional(readOnly = true)
	public Deal getDealById(Integer id, String lang) {

		return dealDAO.findDealById(id, lang);
	}

	@Transactional
	@CacheEvict(value = "deals", allEntries = true)
	public Deal addOrUpdateDeal(Deal deal) {

				
		if (deal.getDealID() == null) {
			deal = dealDAO.saveDeal(deal);
		} else {
			Deal oldDeal = dealDAO.findDealById(deal.getDealID());
			for(Discount oldDiscount : oldDeal.getDiscounts()){		
				Boolean exitInList = false;
				for(Discount newDiscount : deal.getDiscounts()){
					if(newDiscount.getDiscountID() == oldDiscount.getDiscountID()){
						exitInList = true;
					}
				}
				if(oldDiscount.getPurchaseItems().size() == 0 && exitInList == false){
					discountDAO.deleteDiscount(oldDiscount.getDiscountID());
				}
			}
			deal = dealDAO.updateDeal(deal);
		}
	
//		exploredService.addOrUpdateExplored(deal);

		return deal;

	}

	@Transactional
	@CacheEvict(value = "deals", allEntries = true)
	public void removeDeal(Integer id) {
		dealDAO.deleteDeal(id);
	}

	@Transactional(readOnly = true)
	public long countDeals() {
		return dealDAO.countDeals();
	}

	@Transactional
	// @Cacheable(value = "deals")
	public List<Deal> getAllDeals() {
		return dealDAO.findAllDeals();
	}

	@Transactional
	@Cacheable(value = "deals")
	public List<Deal> getDealsEntries(int firstResult, int maxResults) {
		return dealDAO.findDealsEntries(firstResult, maxResults);
	}

	@Transactional
	public Deal getFeaturedDeal(String lang) {
		return dealDAO.getFeaturedDeal(lang);
	}

	@Transactional
	public Deal getDealWithKey(Integer dealID, String lang) {
		return dealDAO.findDealWithKey(dealID, lang);
	}

	@Transactional
	public List<Formula> getFormulasByProductId(Integer productID) {
		return dealDAO.getFormulasByProductId(productID);
	}

	@Transactional
	public List<Deal> getAllDeals(String lang) {
		return dealDAO.findAllDeals(lang);
	}

	@Transactional
	// @Cacheable(value = "deals")
	public List<Deal> getDealsbyTag(String lang, String tag) {
		return dealDAO.findDealsbyTag(lang, tag);
	}

	@Transactional
	public Discount getDiscountByDealID(Integer dealID, Integer formulaID) {
		return dealDAO.getDiscountByDealID(dealID, formulaID);
	}

	@Transactional(readOnly = true)
	public List<PurchaseItem> getPurchaseItemsByDealID(Integer DealID) {
		return dealDAO.findPurchaseItemsByDealID(DealID);
	}

	@Transactional
	public Long expireDeals() {
		return dealDAO.expireDeals();
	}

	public long countDeals(String lang) {
		return dealDAO.countDeals(lang);
	}

	public List<Deal> getDealsEntries(String lang, int firstResult,
			int maxResults) {

		return dealDAO.findDealsEntries(firstResult, maxResults, lang);
	}

	public Deal getDealByLang(Integer localizationKey,
			String localizationRequest) {
		Deal deal = dealDAO
				.findDealByLang(localizationKey, localizationRequest);
		if (deal != null) {
			return deal;
		} else {
			Deal newDeal = dealDAO
					.findDealByArticleLocalization(localizationKey);
			newDeal.getArticlesLocalization().setArticles(null);
			return newDeal;
		}
	}

	public Deal getDealByArticleID(Integer id) {
		return dealDAO.findDealByArticleID(id);
	}

	public List<Deal> getNewDealsEntries(String lang, int firstResult,
			int maxResults) {
		return dealDAO.findNewDealsEntries(firstResult, maxResults, lang);
	}

	public List<Deal> getPopularDealsEntries(String lang, int firstResult,
			int maxResults) {
		return dealDAO.findPopularDealsEntries(firstResult, maxResults, lang);
	}

	public List<Deal> getEndSoonDealsEntries(String lang, int firstResult,
			int maxResults) {
		return dealDAO.findEndSoonDealsEntries(firstResult, maxResults, lang);
	}

	public Map<String, Object> search(String searchText,
			ConcurrentHashMap<String, Object> searchResult) {
		return searchResult;
	}

	public List<Deal> getDealsbyProduct(String lang, Integer productID,
			int firstResult, int maxResults) {
		return dealDAO.findDealsbyProduct(lang, productID, firstResult, maxResults);
	}

	public long countDeals(String lang, Integer productID) {
		return dealDAO.countDeals(lang, productID);
	}

}
